// Package
// @author: BaiYZ
// @description:
// @file: client
// @version: 1.0.0
// @date: 2022/6/8 17:24
package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
)

const BUFFER_SIZE int = 4096

type Client struct {
	ServerIp   string
	ServerPort int
	Name       string
	conn       net.Conn
	flag       int
}

// menu
// @Description: 菜单函数
// @receiver client
// @return bool
func (client *Client) menu() bool {
	var flag int
	fmt.Println("1. Private chat mode")
	fmt.Println("2. Public chat mode")
	fmt.Println("3. Rename mode")
	fmt.Println("0. exit")
	fmt.Println("please Input : ")
	//读取选项
	_, err := fmt.Scanln(&flag)
	if err != nil {
		fmt.Println("--read choose error !")
		return false
	}
	if flag >= 0 && flag <= 3 {
		//存储客户端选项，方便业务处理
		client.flag = flag
		return true
	}
	fmt.Println("--input format error !")
	return false
}

// NewClient
// @Description: 创建client
// @param serverIp
// @param serverPort
// @return *Client
func NewClient(serverIp string, serverPort int) *Client {
	//创建客户端对象
	client := &Client{
		ServerIp:   serverIp,
		ServerPort: serverPort,
		//客户端菜单选项默认值
		flag: 999,
	}
	//连接服务器
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", serverIp, serverPort))
	if err != nil {
		fmt.Println("--client error: ", err)
		return nil
	}
	client.conn = conn
	//返回对象
	return client
}

// UpdateUserName
// @Description: 更新用户名
// @receiver client
// @param newName
// @return bool
func (client *Client) UpdateUserName() bool {
	//提示输入
	fmt.Print("please input new userName:")
	//使用reader避免空格后无法读入
	reader := bufio.NewReader(os.Stdin)
	line, _, readNameError := reader.ReadLine()
	client.Name = string(line)
	if readNameError != nil {
		fmt.Println("--scan input new Name  error :", readNameError)
		return false
	}
	//_, scanErr := fmt.Scanln(&client.Name)
	//if scanErr != nil {
	//	fmt.Println("--scan input new Name  error :", scanErr)
	//	return false
	//}
	//拼接消息
	msg := "rename|" + client.Name
	//发送消息
	_, writeErr := client.conn.Write([]byte(msg))
	if writeErr != nil {
		fmt.Println("--write to server error :", writeErr)
		return false
	}
	return true
}

// PublicChat
// @Description: 公聊功能
// @receiver client
func (client *Client) PublicChat() {
	//获取用户输入
	var msg string
	fmt.Println("please input msg (input \"exit\" to exit!): ")
	//使用reader避免空格后无法读入
	reader := bufio.NewReader(os.Stdin)
	line, _, readPublicMsgError := reader.ReadLine()
	msg = string(line)
	if readPublicMsgError != nil {
		fmt.Println("--read public chat msg error :", readPublicMsgError)
		return
	}

	//_, scanErr := fmt.Scanln(&msg)
	//if scanErr != nil {
	//	fmt.Println("--system scan error: ", scanErr)
	//	return
	//}

	for msg != "exit" {
		//重置当前消息
		msg = ""
		fmt.Println("please input msg (input \"exit\" to exit!): ")
		//使用reader避免空格后无法读入
		reader := bufio.NewReader(os.Stdin)
		line, _, readPublicMsgError := reader.ReadLine()
		msg = string(line)
		if readPublicMsgError != nil {
			fmt.Println("--read public chat msg error :", readPublicMsgError)
			return
		}
		//不为空发送服务器
		if msg != "" {
			sendMsg := msg + "\n"
			_, sendErr := client.conn.Write([]byte(sendMsg))
			if sendErr != nil {
				fmt.Println("--system msg send error: ", sendErr)
				return
			}
		}
	}
}

// GetAllUsers
// @Description: 获取全部在线用户信息
// @receiver client
func (client *Client) GetAllUsers() {
	getAllUsers := "who\n"
	_, getAllUserError := client.conn.Write([]byte(getAllUsers))
	if getAllUserError != nil {
		fmt.Println("--get all user error: ", getAllUserError)
		return
	}
}

// PrivateChat
// @Description: 私聊模式
// @receiver client
func (client *Client) PrivateChat() {
	//查询用户在线
	client.GetAllUsers()
	//选择用户
	fmt.Println("please input user name (input \"exit\" to exit!): ")
	var toUser string
	//使用reader避免空格后无法读入
	reader := bufio.NewReader(os.Stdin)
	line, _, readToUserError := reader.ReadLine()
	toUser = string(line)
	if readToUserError != nil {
		fmt.Println("--read toUser input new Name  error :", readToUserError)
		return
	}
	var msg string
	for msg != "exit" {
		//初始化msg
		msg = ""
		//提示用户输入发送消息
		fmt.Println("please input msg :")
		//使用reader避免空格后无法读入
		reader := bufio.NewReader(os.Stdin)
		line, _, readPrivateMsgError := reader.ReadLine()
		msg = string(line)
		if readPrivateMsgError != nil {
			fmt.Println("--read private chat msg error :", readPrivateMsgError)
			return
		}

		//_, scanUserMsgError := fmt.Scanln(&msg)
		//if scanUserMsgError != nil {
		//	fmt.Println("--scan msg error : ", scanUserMsgError)
		//	return
		//}
		//不为空发送服务器
		if msg != "" {
			sendMsg := "to|" + toUser + "|" + msg + "\n"
			_, sendMsgError := client.conn.Write([]byte(sendMsg))
			if sendMsgError != nil {
				fmt.Println("--send msg error : ", sendMsgError)
				return
			}
		}
	}
	fmt.Println("--you had exit private chat mode !")
}

// DealResp
// @Description: 显示服务器回复信息
// @receiver client
func (client *Client) DealResp() {
	//永久阻塞等待套接字内容，存在就会拷贝到标准输出
	//与如下相同
	/*	_, err := io.Copy(os.Stdout, client.conn)
		if err != nil {
			fmt.Println("--receive server msg has error : ", err)
		}*/

	for {
		buffer := make([]byte, BUFFER_SIZE)
		n, err := client.conn.Read(buffer)
		if err != nil {
			return
		}
		serverMsg := string(buffer[:n-1])
		if serverMsg == "[system]:block" {
			fmt.Println("------exit-client-----")
			os.Exit(-1)
		}
		fmt.Println(serverMsg)
	}
}
